from django.db import models
from base import *
from object_types import *
from simdb import *

_model_names = ["Protocol", "Physics", "InputParameter", 
                "ParameterGroup",
                "RepresentationObjectType", "Algorithm", "FileType"]
__all__ = _model_names + ["REPRESENTATION_TYPES"] 

REPRESENTATION_TYPES = (('point particle',
                         'Represents the case where point particles are used to represent the simulated world.'),
                        ('SPH particle',
                         'Represents the case where extended particles with hydro properties are used to represent the simulated world in an SPH simulation.'),
                        ('extended particle',
                         'Represents the case where extended particles are used to represent the simulated world.'),
                        ('simple mesh cell',
                         'Represents the case where simple, non-structured/subdivided mesh cells are used to represent the simulated world in a regular grid.'),
                        ('hierarchical mesh cell',
                         'Represents the case where mesh cells that may be hierarchically subdivided are used to represent the simulated world in an adaptive mesh refinemenet simulation.'),
                        ('model astro object',
                         'Represents the case where mock astronomical objects with their "physical" properties are used to represent the simulated world. Mainly found in results of post-processing. Examples are dark matter halos as the result of a cluster finder, synthetic galaxies as the result of semi-analytical simulations or halo occupation distributions algorithms.'),
                        ('custom',
                         'Represents the case wherecustom objects, for which there is no existing term available in this enumeration, are used to represent the simulated world.'))

PROTOCOL_TYPES = (('simulator',
                   'Simulator: Evolves the state of a system using a model.'),
                  ('initial conditions generator',
                   'Initial conditions generator: Instantiates the representation of a system based on a physical model.'),
                  ('projection tool',
                   'Projection tool: Generates a two dimensional array by integration or ray casting.'),
                  ('halo finder',
                   'Halo finder: Finds gravitational bound systems based using particle data.'),
                  ('clump finder',
                   'Clump finder: Finds gravitational bound systems based using field, or grid data.'),
                  ('extraction tool',
                   'Extraction tool: Creates a uniform grid from larger, possibly hierarchical grid.'),
                  ('custom',
                   'Custom tool: Performs specialized analysis or post-processing on existing data.'))

class Protocol(Resource):
    _collection_sets = []
    element_name = 'aProtocol'
    source = models.URLField(blank=True, verify_exists=False)
    type = models.CharField(max_length=256,
                            choices=PROTOCOL_TYPES, default='simulator')
    version = models.CharField(max_length=1024, blank=True)

class InputParameter(Field):
    _collection_sets = []
    protocol = models.ForeignKey(Protocol)
    default = models.CharField(max_length=1024, blank=True)
    label = models.CharField(max_length=1024, blank=True)
    _container_field = "protocol_id"
    Protocol._collection_sets.append('inputparameter_set')

class ParameterGroup(MetadataObject):
    _collection_sets = []
    protocol = models.ForeignKey(Protocol)
    name = models.CharField(max_length=256)
    description = models.TextField(blank=True)
    parameters = models.ManyToManyField(InputParameter)
    _container_field = "protocal_id"
    Protocol._collection_sets.append('parametergroup_set')

    def __unicode__(self):
        return u'%s: %s' % (self.protocol.name, self.name)

class Algorithm(MetadataObject):
    _collection_sets = []
    protocol = models.ForeignKey(Protocol)
    name = models.CharField(max_length=256)
    description = models.TextField(blank=True)
    label = models.CharField(max_length=256, blank=True)
    _container_field = "protocol_id"
    Protocol._collection_sets.append('algorithm_set')

    def __unicode__(self):
        return u'%s: %s' % (self.protocol.name, self.name)

class RepresentationObjectType(ObjectType):
    _collection_sets = []
    protocol = models.ForeignKey(Protocol)
    type = models.CharField(max_length=256,
                            choices=REPRESENTATION_TYPES, default='custom')
    label = models.CharField(max_length=1024, blank=True)
    _container_field = "protocol_id"
    Protocol._collection_sets.append('representationobjecttype_set')

    def __unicode__(self):
        return u'%s: %s' % (self.protocol.name, self.name)

class Physics(MetadataObject):
    _collection_sets = []
    protocol = models.ForeignKey(Protocol)
    name = models.CharField(max_length=256, blank=True)
    description = models.TextField(blank=True)
    texform = models.TextField(blank=True)
    physicslabel = models.CharField(max_length=256, blank=True)
    _container_field = "protocol_id"
    Protocol._collection_sets.append('physics_set')

    def __unicode__(self):
        return u'%s: %s' % (self.protocol.name, self.name)

class FileType(MetadataObject):
    _collection_sets = []
    protocol = models.ForeignKey(Protocol)
    name = models.CharField(max_length=1024)
    description = models.TextField(blank=True)    
    mime_type = models.CharField(max_length=256, blank=True)
    _container_field = "protocol_id"
    Protocol._collection_sets.append('filetype_set')

    def __unicode__(self):
        return u'%s: %s' % (self.protocol.name, self.name)
